package net.homelinux.chaoswg.io.renga.krypto.operations.type;

import java.math.BigInteger;

import net.homelinux.chaoswg.io.datatypes.Pair;
import net.homelinux.chaoswg.io.higherorderfunctions.AbstractUnaryFunction;
import net.homelinux.chaoswg.io.higherorderfunctions.UnaryFunction;
import net.homelinux.chaoswg.io.renga.krypto.datatypes.numerical.UnsignedNBit;
import net.homelinux.chaoswg.io.renga.krypto.datatypes.numerical.UnsignedNBitFactory;

public class Split2 extends  AbstractUnaryFunction<Pair<UnsignedNBit, UnsignedNBit>, UnsignedNBit> implements UnaryFunction<Pair<UnsignedNBit, UnsignedNBit>, UnsignedNBit> {
    public Pair<UnsignedNBit,UnsignedNBit> apply (final UnsignedNBit unb) {
        final UnsignedNBitFactory unbFactory = UnsignedNBitFactory.createUnsignedNBitFactory();
        final int toSplitInto = 2;
        
        if (unbFactory.exists(unb.getN()/toSplitInto)) {
            final BigInteger [] u = new BigInteger [toSplitInto];
            final UnsignedNBit [] unbs = new UnsignedNBit [toSplitInto];

            final BigInteger val = unb.getValue();

            final BigInteger tmpMAX = unbFactory.get(unb.getN()/toSplitInto).getMAX();
            final int divSize = unb.getN() / toSplitInto;

            for (int i = 0; i < toSplitInto; ++i) {
                u[i] = val.shiftRight(i * divSize).and(tmpMAX);
                unbs [i] = unbFactory.get(divSize);
                unbs [i].setValue(u[i]);            
            }
            
            return new Pair<UnsignedNBit, UnsignedNBit>(unbs[1], unbs[0]);
        }
        return null;
    }
    
    public String toString () {
        return "Split into two";
    }
}
